<template>
  <div class="employees-container">
    <div class="app-container">
      <!-- 页头组件 -->
      <page-header>
        <!-- 给左侧插槽分发标签 -->
        <template #left>
          <span>总记录数: {{ total }} 条</span>
        </template>
        <!-- 给右侧插槽分发标签 -->
        <template #right>
          <el-button
            type="warning"
            size="small"
            @click="$router.push('/import-excel')"
            >Excel导入</el-button
          >
          <el-button type="danger" size="small" @click="handleExport"
            >Excel导出</el-button
          >
          <el-button
            type="primary"
            size="small"
            @click="isVisible = true"
            v-if="$checkPermission('POINT_EMPLOYEE_ADD')"
            >新增员工</el-button
          >
        </template>
      </page-header>
      <!-- 表格 + 分页 -->
      <el-card style="margin-top: 10px">
        <el-table border :data="employeeList">
          <el-table-column
            label="序号"
            sortable
            type="index"
            :index="indexMethod"
            width="80"
          />
          <el-table-column label="头像" sortable>
            <template #default="{ row }">
              <!-- v-if条件判断：如果staffPhoto不为空，则展示头像 -->
              <!-- 如果staffPhoto不为空，有可能不能正常显示，借助v-imgerror自定义指令 -->
              <img
                @click="showQrCode(row.staffPhoto)"
                v-if="row.staffPhoto"
                :src="row.staffPhoto"
                v-imgerror="
                  'https://img1.baidu.com/it/u=2474074913,3627667591&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1667235600&t=ef9e3c363fcfcaed42dabe7b7e612516'
                "
              />
              <!-- 否则展示默认头像 -->
              <img
                @click="showQrCode"
                v-else
                src="https://img2.baidu.com/it/u=331567426,1634440262&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1667235600&t=c77c6b88c567024e7bb650405e626bc0"
              />
            </template>
          </el-table-column>
          <el-table-column label="姓名" sortable prop="username" />
          <el-table-column label="手机号" sortable prop="mobile" />
          <el-table-column label="工号" sortable prop="workNumber" />
          <el-table-column
            label="聘用形式"
            sortable
            prop="formOfEmployment"
            :formatter="formatFormOfEmployment"
          />
          <el-table-column label="部门" sortable prop="departmentName" />
          <el-table-column label="入职时间" sortable prop="timeOfEntry" />
          <el-table-column label="操作" fixed="right" width="280">
            <template #default="{ row }">
              <el-button
                type="text"
                size="small"
                @click="$router.push(`/employees/${row.id}`)"
                >查看</el-button
              >
              <el-button type="text" size="small">转正</el-button>
              <el-button type="text" size="small">调岗</el-button>
              <el-button type="text" size="small">离职</el-button>
              <el-button type="text" size="small" @click="handleFn(row.id)"
                >角色</el-button
              >
              <el-button
                type="text"
                size="small"
                @click="handleDel(row.id)"
                v-if="$checkPermission('POINT_EMPLOYEE_DELETE')"
                >删除</el-button
              >
              <el-button></el-button>
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页组件 -->
        <div style="height: 60px; margin-top: 10px">
          <el-pagination
            background
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="query.page"
            :page-sizes="[2, 3, 5, 10]"
            :page-size="query.size"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
          >
          </el-pagination>
        </div>
      </el-card>
      <!-- 添加员工组件 -->
      <add-employee
        :showDialog="isVisible"
        @on-close="isVisible = false"
        @on-add-success="getEmployeeList"
      />
      <!-- 二维码弹框 -->
      <el-dialog
        class="qrcode-dialog"
        :visible="isShow"
        title="二维码"
        @close="isShow = false"
        width="400px"
      >
        <canvas ref="qrCodeRef"></canvas>
      </el-dialog>
      <!-- 分配角色弹框 -->
      <assign-role
        :showDialog="isShowAssignRole"
        @on-close="isShowAssignRole = false"
        :userId="userId"
      />
    </div>
  </div>
</template>

<script>
import { getEmployeeListAPI, delEmployeeAPI } from "@/api/employees";
// 导入常量模块数据
import obj from "@/constant/employees";
import QrCode from "qrcode";
import AssignRole from "./components/assign-role.vue";
import AddEmployee from "./components/add-employee.vue";
export default {
  name: "Employees",
  components: {
    AddEmployee,
    AssignRole,
  },
  data() {
    return {
      // 查询对象
      query: {
        page: 1, // 页码
        size: 5, // 条数
      },
      // 员工列表
      employeeList: [],
      // 总条数
      total: 0,
      // 控制添加员工子组件的可见性
      isVisible: false,
      isShow: false,
      isShowAssignRole: false,
      // 记录当前选择的员工ID
      userId: "",
    };
  },
  created() {
    console.log(this);
    this.getEmployeeList();
  },
  methods: {
    // 点击角色按钮时
    handleFn(id) {
      // 1. 显示分配角色弹框
      this.isShowAssignRole = true;
      // 2. 记录当前选择的userId
      this.userId = id;
    },
    // 展示二维码
    async showQrCode(imgUrl) {
      // 1. 显示弹框
      this.isShow = true;
      // 2. 生成二维码显示
      // 说明：isShow设置true之后，el-dialog会显示，但是
      // this.$refs.qrCodeRef 这句代码是异步执行的，需要排队
      // 需要用  this.$nextTick()包一下，确保在回调中DOM更新完毕
      // 才可获取到
      // this.$nextTick(() => {
      //   QrCode.toCanvas(this.$refs.qrCodeRef, imgUrl);
      // });
      // this.$nextTick()返回值是个Promise实例，如果不想写回调，
      // 可以用await + async来简化
      await this.$nextTick();
      QrCode.toCanvas(this.$refs.qrCodeRef, imgUrl);
    },
    // 处理 excel 的导出
    async handleExport() {
      // 1. 导入实现 excel 导出的核心模块
      const excel = await import("@/vendor/Export2Excel");
      // 2. 把数组数据放到 excel 中实现下载
      // 2.1 准备表头
      const tHeader = [
        "姓名",
        "手机号",
        "入职日期",
        "聘用形式",
        "转正日期",
        "工号",
        "部门",
      ];
      // 2.2 准备表体数据(基于total再发送一次请求，获取所有的条数)
      // 页码设置为1
      this.query.page = 1;
      // 当前请求条数设置为total总条数
      this.query.size = this.total;
      // 根据新的query对象，获取所有员工列表（调api目录下接口函数）
      const resp = await getEmployeeListAPI(this.query);
      // 保存所有的员工对象（对象数组）

      const rows = resp.data.rows;
      // 对 rows 做处理 -> 转换为二维数组
      // data就是二维数组
      const data = this.handleRows(rows, tHeader);
      excel.export_json_to_excel({
        // 表头
        header: tHeader,
        // 表体（二维数组） -> [[], [], []]
        data,
        filename: `${this.$store.state.user.profile.company}员工信息表`,
      });
    },
    // 处理rows对象数组，目的是把对象变成数组
    // 最后得到一个二维数组
    handleRows(rows, theader) {
      // 中英文键的映射关系（一个对象来描述）
      const headersRelations = {
        姓名: "username",
        手机号: "mobile",
        入职日期: "timeOfEntry",
        聘用形式: "formOfEmployment",
        转正日期: "correctionTime",
        工号: "workNumber",
        部门: "departmentName",
      };
      // 大数组，用来装结果
      const bigArr = [];
      // 遍历rows（对象数组）
      for (let i = 0; i < rows.length; i++) {
        // 小数组，作为大数组中小数组存在
        const smallArr = [];
        // row就是每个员工对象
        const row = rows[i];
        // 遍历表头数组
        for (let j = 0; j < theader.length; j++) {
          // zhKey是中文键
          let zhKey = theader[j];
          // 根据中文键取出相应的英文键
          let enKey = headersRelations[zhKey];
          // 如果英文键是 formOfEmployment，这个属性值
          // 是个数字，需要转换为对应的中文
          if (enKey === "formOfEmployment") {
            // 查找对应的聘用形式对象
            const item = obj.hireType.find((item) => item.id === +row[enKey]);
            // 把中文含义放入小数组
            smallArr.push(item ? item.value : "未知");
          } else {
            // 取出英文键对应的值，放入小数组
            smallArr.push(row[enKey]);
          }
        }
        // 小数组装入大数组
        bigArr.push(smallArr);
      }
      // 返回大数组（二维数组）
      return bigArr;
    },
    // 获取员工列表
    async getEmployeeList() {
      // 1. 调接口、发请求
      const {
        data: { rows, total },
      } = await getEmployeeListAPI(this.query);
      // 2. 保存后台数据
      this.employeeList = rows;
      this.total = total;
    },
    // 格式化聘用形式
    formatFormOfEmployment(row) {
      // row：每一行的员工对象
      // 把数字和中文含义的对应关系，通过对象来描述
      // const obj = {
      //   1: "正式",
      //   2: "非正式",
      //   3: "实习生",
      //   4: "钟点工",
      // };
      // 返回对应的值(给用户展示)
      // 好处：避免书写很多冗余的if分支判断
      const item = obj.hireType.find(
        // 这里为啥添加+号？因为后台给的这个
        // row.formOfEmployment 是个字符串，需要转换数字
        (item) => item.id === +row.formOfEmployment
      );
      return item ? item.value : "未知";
    },
    // 页码变化时
    handleCurrentChange(page) {
      // 同步最新的页码
      this.query.page = page;
      // 根据新的页码获取列表
      this.getEmployeeList();
    },
    // 条数变化时
    handleSizeChange(size) {
      // 同步最新的条数
      this.query.size = size;
      // 根据新的条数获取列表
      this.getEmployeeList();
    },
    // 处理分页序号，不断递增
    indexMethod(index) {
      return index + 1 + (this.query.page - 1) * this.query.size;
    },
    // 删除
    async handleDel(employeeID) {
      try {
        // 1. 询问
        await this.$confirm("此操作不可逆、确定删除么?", "温馨提示", {
          type: "warning",
        });
        // 2. 确定
        // 2.1 调用删除接口
        await delEmployeeAPI(employeeID);
        // 2.2 给个成功提示
        this.$message.success("员工删除成功");
        // 2.3 获取员工列表
        this.getEmployeeList();
      } catch (e) {
        // 3. 取消
        // 3.1 给个提示
        this.$message.info("已取消");
      }
    },
  },
};
</script>

<style scoped lang="scss">
img {
  width: 70px;
  height: 70px;
  border-radius: 50%;
}
// 样式穿透，深层选择组件内部的标签
.qrcode-dialog {
  ::v-deep {
    .el-dialog__body {
      text-align: center;
    }
  }
}
</style>
